#include "kernel/vfs/vfs.h"
#include "kernel/vfs/fat32.h"
#include "kernel/log/log.h"
#include "kernel/driver/disk.h"

SuperBlock::SuperBlock(/* args */)
{
}

SuperBlock::~SuperBlock()
{
}

void SuperBlock::writeInode(IndexNode* inode)
{


    FAT32_Directory* fdentry = NULL;
    FAT32_Directory* buf = NULL;
    FAT32_inode_info* finode =(FAT32_inode_info*)inode->privateIndexInfo;
    FAT32_sb_info* fsbi = (FAT32_sb_info*)inode->sb->privateSbInfo;

    if(finode->dentry_location == 0){

        LOG_ERROR("FS ERROR:write root inode\n");
        return;

    }

    uint64_t sector = fsbi->Data_firstsector + (finode->dentry_location - 2) * fsbi->sector_per_cluster;
    
    buf = (FAT32_Directory*)new char[fsbi->bytes_per_cluster];
    memset(buf,0,fsbi->bytes_per_cluster);
    DISKMANAGER->readDisk(0x1,sector,fsbi->sector_per_cluster,(uint8_t*)(buf));
    fdentry = (FAT32_Directory*)(buf + finode->dentry_position);


    fdentry->DIR_FileSize = inode->fileSize;
    fdentry->DIR_FstClusLO = finode->first_cluster & 0xffff;
    fdentry->DIR_FstClusHI = (fdentry->DIR_FstClusHI & 0xf000) | (finode->first_cluster >> 16);
    
    DISKMANAGER->writeDisk(0x1,sector,fsbi->sector_per_cluster,(uint8_t*)buf);

    delete buf;


}


IndexNode::IndexNode(/* args */)
{
}



IndexNode::~IndexNode()
{
}

DirEntry* IndexNode::create(DirEntry* dentry,char* name,uint64_t attribute)
{
    
}


DirEntry* IndexNode::lookup(IndexNode * parent_inode,DirEntry * dest_dentry)
{
    


   

}





DirEntry::DirEntry(/* args */)
{

}

DirEntry::~DirEntry()
{

}




File::File(/* args */)
{
}

File::~File()
{
}

int64_t File::open(IndexNode* inode,File* filp)
{
    return 1;
}

int64_t File::close(IndexNode* inode,File* filp)
{
    return 1;
}

int64_t File::read(char* buf, uint64_t count,int64_t* position)
{
     LOG_ERROR("file read\n");
}

int64_t File::write(char* buf, uint64_t count,int64_t* position)
{
    
}

int64_t File::lseek(int64_t offset, int64_t origin)
{
    
}

int64_t File::ioctl(IndexNode* inode,File* filp,uint64_t cmd,uint64_t arg)
{
    
}




FileSystem::FileSystem(/* args */)
{
}

FileSystem::~FileSystem()
{
}


SuperBlock* FileSystem::readSuperBlock(void* buf){



}

VFS* VFS::vfsm;
VFS::VFS(/* args */)
{

    vfsm = this;

    fileSystem.name = new char[2];
    memset(fileSystem.name,0,2);



}

VFS::~VFS()
{
    delete fileSystem.name;
}


SuperBlock* VFS::mountFs(char* name,void* buf){

    for(FileSystem* fs = &fileSystem;fs;fs = fs->next){

        if(!strcmp(fs->name,name)){

            return fs->readSuperBlock(buf);

        }
        
    }

    return NULL;

}

uint64_t VFS::addFilesystem(FileSystem* fs){

   
    for(FileSystem* p = &fileSystem;p;p = p->next){


        if(!strcmp(fs->name,p->name)){

            return 0;

        }

    }

    fs->next = fileSystem.next;

    fileSystem.next = fs;

    return 1;



}